package ru.amse.tsyganov.jumleditor.graphicaleditor;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;

import ru.amse.tsyganov.jumleditor.model.Decision;
import ru.amse.tsyganov.jumleditor.model.State;
import ru.amse.tsyganov.jumleditor.model.Transition;
import ru.amse.tsyganov.jumleditor.view.activepoints.ActivePoint;
import ru.amse.tsyganov.jumleditor.view.preferences.Cursors;
import ru.amse.tsyganov.jumleditor.view.representation.StateView;
import ru.amse.tsyganov.jumleditor.view.representation.TransitionView;

/*package*/ class SelectionMode extends EditorMode {
	
	private final GraphicalEditor graphicalEditor;
	
	private boolean mouseButtonPressed = false;
	
	private StateView<? extends State> currentSelectedStateView;
	
	private TransitionView<? extends Transition> currentSelectedTransition;
	
	public SelectionMode(GraphicalEditor graphicalEditor) {
		if (graphicalEditor == null) {
			throw new IllegalArgumentException();
		}
		this.graphicalEditor = graphicalEditor;	
	}
	
	@Override
	public void initState() {
		graphicalEditor.getCanvas().setCursor(Cursors.getCursorArrow());
		graphicalEditor.getActivityGraphView().setPaintConnectionPoints(false);
		mouseButtonPressed = false;
		currentSelectedStateView = null;
		currentSelectedTransition = null;
		graphicalEditor.getCanvas().redraw();
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if (e.keyCode == SWT.F2) {
			if (graphicalEditor.getActivityGraphView().getSelectedItems().selectedStatesSize() +
					graphicalEditor.getActivityGraphView().getSelectedItems().
						selectedTransitionsSize() == 1) {
				
				if (graphicalEditor.getActivityGraphView().getSelectedItems().
						selectedStatesSize() == 1) {
				
					StateView<? extends State> selectedState = 
						graphicalEditor.getActivityGraphView().getSelectedItems().
							getSelectedStates().iterator().next();
				
					if (selectedState.getMainProperty() != null) {
						graphicalEditor.setEditorMode(graphicalEditor.getTextInputMode());
					}
				}
				
				if (graphicalEditor.getActivityGraphView().getSelectedItems().
						selectedTransitionsSize() == 1) {
				
					TransitionView<? extends Transition> selectedTransition = 
						graphicalEditor.getActivityGraphView().getSelectedItems().
							getSelectedTransitions().iterator().next();
				
					if (selectedTransition.getMainProperty() != null) {
						graphicalEditor.setEditorMode(graphicalEditor.getTextInputMode());
					}
				}
			}
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
	}

	@Override
	public void mouseDoubleClick(MouseEvent e) {
		StateView<? extends State> selectedView = 
			graphicalEditor.getActivityGraphView().getStateView(e.x, e.y);
		
		if (selectedView != null && 
				selectedView.getMainProperty() != null) {
			
			graphicalEditor.getActivityGraphView().getSelectedItems().
				selectedStatesClear();
			
			graphicalEditor.getActivityGraphView().getSelectedItems().
				selectedTransitionsClear();
			
			graphicalEditor.getActivityGraphView().getSelectedItems().
				selectedStatesAdd(selectedView);
			
			graphicalEditor.setEditorMode(graphicalEditor.getTextInputMode());
		}
		
		TransitionView<? extends Transition> selectedTransition = 
			graphicalEditor.getActivityGraphView().getTransitionView(e.x, e.y);
		
		if (selectedTransition != null) {
			if (!selectedTransition.getModel().isGuard()) {
				if (selectedTransition.getModel().getSource().getContainer() 
						instanceof Decision) {
					selectedTransition.getModel().setGuard(true);
				} else {
					return;
				}
			}
			
			graphicalEditor.getActivityGraphView().getSelectedItems().
				selectedStatesClear();
			
			graphicalEditor.getActivityGraphView().getSelectedItems().
				selectedTransitionsClear();
			
			graphicalEditor.getActivityGraphView().getSelectedItems().
				selectedTransitionsAdd(selectedTransition);
			
			graphicalEditor.setEditorMode(graphicalEditor.getTextInputMode());
		}
	}

	@Override
	public void mouseDown(MouseEvent e) {
		mouseButtonPressed = true;
		
		ActivePoint selectedActivePoint = 
			graphicalEditor.getActivityGraphView().getActivePoint(e.x, e.y);
		
		StateView<? extends State> selectedView = 
			graphicalEditor.getActivityGraphView().getStateView(e.x, e.y);
		
		TransitionView<? extends Transition> selectedTransition = 
			graphicalEditor.getActivityGraphView().getTransitionView(e.x, e.y);
		
		if (graphicalEditor.isShiftOrCtrlPressed()) {
			if (selectedView != null) {
				if (graphicalEditor.getActivityGraphView().getSelectedItems().
						selectedStatesContains(selectedView)) {
					
					currentSelectedStateView = selectedView;
				} else {
					graphicalEditor.getActivityGraphView().getSelectedItems().
						selectedStatesAdd(selectedView);
				}
			} else if (selectedTransition != null) {
				if (graphicalEditor.getActivityGraphView().getSelectedItems().
						selectedTransitionsContains(selectedTransition)) {
					
					currentSelectedTransition = selectedTransition;
				} else {
					graphicalEditor.getActivityGraphView().getSelectedItems().
						selectedTransitionsAdd(selectedTransition);
				}
			} 
		} else {
			if (selectedActivePoint != null) {
				EditorMode mode = new TrackingActivePointMode(
						selectedActivePoint, graphicalEditor);
				mode.mouseMove(e);
				graphicalEditor.setEditorMode(mode);
				return;
			}
			
			if (selectedView == null || !graphicalEditor.getActivityGraphView().
					getSelectedItems().selectedStatesContains(selectedView)) {
			
				graphicalEditor.getActivityGraphView().getSelectedItems().
					selectedStatesClear();
			
				graphicalEditor.getActivityGraphView().getSelectedItems().
					selectedTransitionsClear();
			}
			
			if (selectedView != null) {
				graphicalEditor.getActivityGraphView().
					getSelectedItems().selectedStatesAdd(selectedView);
			} else if (selectedTransition != null) {
				graphicalEditor.getActivityGraphView().
					getSelectedItems().selectedTransitionsAdd(selectedTransition);
			}
		}
	}

	@Override
	public void mouseMove(MouseEvent e) {
		
		ActivePoint selectedActivePoint = 
			graphicalEditor.getActivityGraphView().getActivePoint(e.x, e.y);
		
		StateView<? extends State> selectedView = 
			graphicalEditor.getActivityGraphView().getStateView(e.x, e.y);
		
		TransitionView<? extends Transition> selectedTransition = 
			graphicalEditor.getActivityGraphView().getTransitionView(e.x, e.y);
		
		if (mouseButtonPressed && 
				(selectedView != null || selectedTransition != null)) {
			
			EditorMode mode = new TrackingStateMode(graphicalEditor, e.x, e.y);
			mode.mouseMove(e);
			graphicalEditor.setEditorMode(mode);
		}

		if (selectedActivePoint != null) {
			graphicalEditor.getCanvas().setCursor(selectedActivePoint.getCursor());
		} else if (selectedView != null && 
				graphicalEditor.getActivityGraphView().getSelectedItems().
					selectedStatesContains(selectedView)) {
		
			graphicalEditor.getCanvas().setCursor(Cursors.getCursorSizeAll());
		} else {
			graphicalEditor.getCanvas().setCursor(Cursors.getCursorArrow());
		}
		
		if (mouseButtonPressed && selectedView == null && selectedTransition == null) {
			
			graphicalEditor.setEditorMode(graphicalEditor.getAreaSelectionMode());
			graphicalEditor.getAreaSelectionMode().mouseDown(e);
		}
	}

	@Override
	public void mouseUp(MouseEvent e) {
		mouseButtonPressed = false;
		
		if (currentSelectedStateView != null) {
			graphicalEditor.getActivityGraphView().getSelectedItems().
				selectedStatesRemove(currentSelectedStateView);
			
			currentSelectedStateView = null;
		} else if (currentSelectedTransition != null) {
			graphicalEditor.getActivityGraphView().getSelectedItems().
				selectedTransitionsRemove(currentSelectedTransition);
			
			currentSelectedTransition = null;
		}
	}

	@Override
	public void paintControl(PaintEvent e, Coordinates coordinates) {
		
	}
}
